<?php

namespace common\service;


use common\model\StepUpstreamModel;
use support\SingletonTrait;

class StepCategoryDownStreamService
{
    use SingletonTrait;


    /**
     * 下游环节查询
     * @param int $projectId
     * @param int $stepCategoryId
     * @param $workflowIds
     * @return array
     */
    public function get(int $projectId, int $stepCategoryId, $workflowIds)
    {
        // 优先取项目级,如果项目级没配置,则取平台级
        $relationList = model(StepUpstreamModel::class)
            ->field("project_id,step_id dw_id,upstream_step_id uw_id")
            ->where(['project_id' => $projectId])
            ->select();
        if (empty($relationList)) {
            $platformWhere['project_id'] = 0;
            $platformWhere['project_template_id'] = 0;
            if (!empty($workflowIds)) {
                $platformWhere['step_workflow_id'] = ['IN', $workflowIds];
            }
            $relationList = model(StepUpstreamModel::class)
                ->field("project_id,step_id dw_id,upstream_step_id uw_id")
                ->where($platformWhere)
                ->select();
        }

        $stepList = StepService::getInstance()->getList([], 'id,step_category_id');
        $stepList = array_column($stepList, 'step_category_id', 'id');
        $stepCategoryList = StepCategoryService::getInstance()->getList([], '*');

        $topStepCategoryModuleRelation = [];
        foreach (array_filter($stepCategoryList, function ($i) {
            return $i['entity_id'] > 0;
        }) as $topStepCategory) {
            if ($topStepCategory['entity_id'] <= 0) {
                continue;
            }
            $topStepCategoryModuleRelation[$topStepCategory['id']] = module_by_id($topStepCategory['entity_id'])['code'];
        }
        $stepCategoryModuleCodeRelation = [];
        foreach (array_filter($stepCategoryList, function ($i) {
            return $i['parent_id'] > 0;
        }) as $secondStepCategory) {
            if (empty($topStepCategoryModuleRelation[$secondStepCategory['parent_id']])) {
                continue;
            }
            $stepCategoryModuleCodeRelation[$secondStepCategory['id']] = $topStepCategoryModuleRelation[$secondStepCategory['parent_id']];
        }

        $currentModuleCode = $stepCategoryModuleCodeRelation[$stepCategoryId] ?? '';
        if (empty($currentModuleCode)) {
            return [];
        }
        $relationMap = [];
        foreach ($relationList as $relationItem) {
            // 工序不存在或者环节不存在
            if (
                empty($stepList[$relationItem['dw_id']]) ||
                empty($stepList[$relationItem['uw_id']])
            ) {
                continue;
            }
            // 已经存在该下游记录了
            if (
                !empty($relationMap[$stepList[$relationItem['uw_id']]])
                && in_array($stepList[$relationItem['dw_id']], $relationMap[$stepList[$relationItem['uw_id']]])
            ) {
                continue;
            }
            // 找不到对应的所属模块
            if (empty($stepCategoryModuleCodeRelation[$stepList[$relationItem['uw_id']]])
                ||
                empty($stepCategoryModuleCodeRelation[$stepList[$relationItem['dw_id']]])
                ||
                $stepCategoryModuleCodeRelation[$stepList[$relationItem['uw_id']]] != $stepCategoryModuleCodeRelation[$stepList[$relationItem['dw_id']]]
                && $stepCategoryModuleCodeRelation[$stepList[$relationItem['uw_id']]] != 'design'
            ) {
                continue;
            }
            $relationMap[$stepList[$relationItem['uw_id']]][] = $stepList[$relationItem['dw_id']];
        }
        $res = [];
        $this->find($stepCategoryId, $relationMap, $res);
        return $res;
    }

    /**
     * 递归查找
     * @param int $stepCategoryId
     * @param array $relationMap
     * @param array $res
     * @param $maxLevel
     * @return void
     */
    private function find(int $stepCategoryId, array $relationMap, array &$res, $maxLevel = 100)
    {
        if (!isset($relationMap[$stepCategoryId])) {
            return;
        }
        foreach ($relationMap[$stepCategoryId] as $dwStepCategoryId) {
            if (in_array($dwStepCategoryId, $res)) {
                continue;
            }
            $res[] = $dwStepCategoryId;
            $this->find($dwStepCategoryId, $relationMap, $res, $maxLevel);
        }
    }
}
